package com.zyf.workflow.flow;

import com.zyf.workflow.node.Node;
import com.zyf.workflow.work.Work;
import com.zyf.workflow.work.bean.WorkResult;
import com.zyf.workflow.work.bean.WorkTypeEnum;

import java.util.*;

public class WorkFlow {

    private Integer flowId;

    private Work currentWork;

    private WorkFlowCallBack callBack;

    private Map<String, Work> workFlowMap = new LinkedHashMap<>();


    public WorkFlow(Map<String, Work> workFlowMap) {
        this.workFlowMap = workFlowMap;
    }

    public WorkFlowCallBack getCallBack() {
        return callBack;
    }

    public void setCallBack(WorkFlowCallBack callBack) {
        this.callBack = callBack;
    }


    public void start() {
        Set<String> strings = workFlowMap.keySet();
        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String first = iterator.next();
            currentWork = workFlowMap.get(first);
            break;
        }

        while (currentWork != null) {
            WorkResult workResult = currentWork.dowWork();
            if (workResult != null) {
                String nextWork = workResult.getNextWork();
                currentWork = workFlowMap.get(nextWork);
            }

        }

        if (callBack != null) {
            callBack.onWorkFlowCompleted();
        }


    }

    @Override
    public String toString() {
        return "WorkFlow{" +
                "flowId=" + flowId +
                ", workFlowMap=" + workFlowMap +
                '}';
    }

    public static class Builder {
        private Map<String, Work> flow = null;
        private WorkFlowCallBack callBack = null;
        private Integer nodeId = 0;

        public Builder() {
            this.flow = new LinkedHashMap<>();
        }

        public Builder withWork(Work work) {

            this.flow.put(work.getWorkName(), work);
            return this;
        }

        public Builder withWork(Work work, String nextWork) {
            work.setNextWork(nextWork);
            this.flow.put(work.getWorkName(), work);
            return this;
        }

        public Builder setCallBack(WorkFlowCallBack callBack) {
            this.callBack = callBack;
            return this;
        }

        public WorkFlow create() {
            WorkFlow workFlow = new WorkFlow(flow);
            workFlow.setCallBack(callBack);
            return workFlow;
        }
    }


}
